package com.maowei.handler;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.maowei.common.CanalConstants;
import com.maowei.common.GlobalConstant;
import com.maowei.entity.BusinessOperateRecordModel;
import com.maowei.event.AbstractEventHandler;
import com.maowei.parser.RowDataCustomParser;
import com.maowei.util.DateUtils;
import com.maowei.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 事件解析基类
 *
 * @author maowei
 * @date 2021/8/25
 */
@Slf4j
public abstract class BaseEventHandler extends AbstractEventHandler {


    public BaseEventHandler(RowDataCustomParser rowDataCustomParser) {
        super(rowDataCustomParser);
    }

    protected void print(JSONObject jsonObject) {
        log.info("数据解析器 : {} 处理后的数据 : {}", this.getRowDataCustomParser().getClass().getName(), jsonObject);
    }

    /**
     * 操作记录对象入库
     *
     * @param businessOperateRecordModel
     */
    protected void toDB(BusinessOperateRecordModel businessOperateRecordModel) {
        //xxMapper.insert()
        //只做示例. 如需实现. 可以自己导入mybatis相关包
    }

    /**
     * 业务解析. 取出关注的字段
     *
     * @param jsonObject
     * @param allColumn      所有字段
     * @param focusedColumns 关注变化的字段(可以只关注部分字段的变化, 若指定了关注的字段, 非关注字段的变化将不会做处理)
     */
    protected BusinessOperateRecordModel parse(JSONObject jsonObject, boolean allColumn, List<String> focusedColumns) {
        if (jsonObject == null) {
            return null;
        }
        Map<String, String> changedColumns = (Map<String, String>) jsonObject.get(CanalConstants.Parser.CHANGED_COLUMN);
        if (StringUtils.isEmpty(changedColumns)) {
            return null;
        }
        //业务操作记录对象的构建
        BusinessOperateRecordModel businessOperateRecordModel = commonParse(jsonObject);
        if (!allColumn) {
            if (StringUtils.isEmpty(focusedColumns)) {
                return null;
            }
            //不必要关注的字段变化
            List<String> unnecessaryColumns = changedColumns.keySet()
                    .stream()
                    .filter(column -> !focusedColumns.contains(column))
                    .collect(Collectors.toList());
            for (String unnecessaryColumn : unnecessaryColumns) {
                changedColumns.remove(unnecessaryColumn);
            }
            if (StringUtils.isEmpty(changedColumns)) {
                return null;
            }
        }
        //JSON格式化操作事件
        businessOperateRecordModel.setOperateEvent(JSONObject.toJSONString(changedColumns));
        return businessOperateRecordModel;
    }

    /**
     * 公共字段的解析
     *
     * @param jsonObject
     * @return
     */
    protected BusinessOperateRecordModel commonParse(JSONObject jsonObject) {
        BusinessOperateRecordModel businessOperateRecordModel = new BusinessOperateRecordModel();
        String eventType = (String) jsonObject.get(CanalConstants.Parser.EVNENT_TYPE);
        businessOperateRecordModel.setOperateEventType(eventType);
        businessOperateRecordModel.setRelationObj((String) jsonObject.get(CanalConstants.Parser.TABLE_NAME));
        if (CanalEntry.EventType.INSERT.name().toLowerCase().equals(eventType)) {
            //新增操作. 操作人取创建人, 操作时间取创建时间
            Map<String, String> afterColumns = (Map<String, String>) jsonObject.get(CanalConstants.Parser.AFTER_COLUMN);
            businessOperateRecordModel.setOperator(afterColumns.get(GlobalConstant.CREATE_BY_COLUMN));
            businessOperateRecordModel.setOperateTime(DateUtils.strToLocalDateTime(afterColumns.get(GlobalConstant.CREATE_TIME_COLUMN)));
            businessOperateRecordModel.setRelationId(afterColumns.get(GlobalConstant.COMMON_PRIMARY_KEY));
        } else if (CanalEntry.EventType.UPDATE.name().toLowerCase().equals(eventType)) {
            //修改/删除操作. 操作人取修改人, 操作时间取修改时间
            Map<String, String> afterColumns = (Map<String, String>) jsonObject.get(CanalConstants.Parser.AFTER_COLUMN);
            businessOperateRecordModel.setOperator(afterColumns.get(GlobalConstant.UPDATE_BY_COLUMN));
            businessOperateRecordModel.setOperateTime(DateUtils.strToLocalDateTime(afterColumns.get(GlobalConstant.UPDATE_TIME_COLUMN)));
            businessOperateRecordModel.setRelationId(afterColumns.get(GlobalConstant.COMMON_PRIMARY_KEY));
        } else if (CanalEntry.EventType.DELETE.name().toLowerCase().equals(eventType)) {
            Map<String, String> beforeColumns = (Map<String, String>) jsonObject.get(CanalConstants.Parser.BEFORE_COLUMN);
            businessOperateRecordModel.setOperator(beforeColumns.get(GlobalConstant.UPDATE_BY_COLUMN));
            businessOperateRecordModel.setOperateTime(DateUtils.strToLocalDateTime(beforeColumns.get(GlobalConstant.UPDATE_TIME_COLUMN)));
            businessOperateRecordModel.setRelationId(beforeColumns.get(GlobalConstant.COMMON_PRIMARY_KEY));
        }
        return businessOperateRecordModel;
    }


}
